package com.example.course.config;

import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @author: i_kun
 * @Desc: o_。
 * @create: 2025-06-23 15:16
 */
// 声明当前类为 Spring 的配置类，用于定义 Redis 相关的 Bean 配置
@Configuration
// 启用 Spring 的缓存注解功能（如 @Cacheable、@CacheEvict 等）
@EnableCaching
// 确保当前配置类在 RedisAutoConfiguration 自动配置完成后加载，避免依赖冲突
// 参考 @AutoConfigureAfter 的作用[11](@ref)
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig {

    /**
     * 创建并配置 RedisTemplate Bean，用于操作 Redis 数据库
     * @param redisConnectionFactory 自动注入的 Redis 连接工厂（由 Spring 管理）
     * @return 配置好的 RedisTemplate 实例
     *
     * 注：
     * 1. 使用 StringRedisSerializer 序列化 key，保证 key 的可读性[3,5](@ref)
     * 2. 使用 GenericJackson2JsonRedisSerializer 序列化 value，支持复杂对象存储[4,9](@ref)
     * 3. 序列化配置可避免 Redis 中存储乱码，并提高跨语言兼容性[2,6](@ref)
     */
    @Bean(name = "redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // 创建 RedisTemplate 实例，指定 key 为 String 类型，value 为 Object 类型
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();

        // 创建字符串序列化器（用于 key 和 hash key）
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // 创建 JSON 序列化器（用于 value 和 hash value），支持对象到 JSON 的转换[4,5](@ref)
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();

        // 设置 Redis 连接工厂（必需）
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // 设置 value 的序列化器（存储对象时转换为 JSON 格式）[3,5](@ref)
        redisTemplate.setValueSerializer(jsonRedisSerializer);
        // 设置 key 的序列化器（保证 key 为可读字符串）[2,6](@ref)
        redisTemplate.setKeySerializer(stringRedisSerializer);

        // 设置 hash 结构的 key 和 value 序列化器（与普通 key/value 一致）[3,9](@ref)
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setHashValueSerializer(jsonRedisSerializer);

        // 返回配置完成的 RedisTemplate 实例
        return redisTemplate;
    }
}
